package edu.gatech.bsbmule.presenter;

import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import edu.gatech.bsbmule.model.CustomizedTimer;
import edu.gatech.bsbmule.model.Game;
import edu.gatech.bsbmule.model.Map;
import edu.gatech.bsbmule.model.Player;
import edu.gatech.bsbmule.util.StatisticsManager;
import edu.gatech.bsbmule.view.IPlayerConfig;
import edu.gatech.bsbmule.view.MainWindow;

/**
 * Presenter for player view and players
 * 
 * @author BSB
 * @version 1.0 10/26/2013
 */
public class PlayerConfigPresenter {
    
	private IPlayerConfig view;
	private int configCounter;
	
	public PlayerConfigPresenter(IPlayerConfig view) {
		this.view = view;		
		configCounter = 1;
	}

	public void configurePlayers(
			final List<Player> modelPlayers,
			final Map map,
			final MapScreenPresenter msp,
			final JPanel panel) {
		view.setOKButtonListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				
				// Make a list of names that has been there
				List<String> currentNames = new ArrayList<String>();
				for (Player p : modelPlayers) {
					currentNames.add(p.getName());
				}
				
				// If names are duplicated
				if (currentNames.contains(view.getPlayerName()))
				{
					JOptionPane.showMessageDialog(MainWindow.getInstance(), "Do not use duplicate names!");
				}
				
				// Else names are not duplicated
				else 
				{
					// Display number of currently configured player
					view.setSequence(configCounter);
					
					// Configure a player and add to game model
					modelPlayers.add(configurePlayer(Game.getInstance()));
					
					if (configCounter == Game.getInstance().getNumberOfPlayers())
					{
						// Set players and period constants
						Game game = Game.getInstance();
						game.setPlayers(modelPlayers);
						game.setTurnOrder();
						game.setPeriodsDim(game.getGameTurn(), game.getNumberOfPlayers());
						game.initPeriods();
						
						// Set up statistics manager
						List<String> names = new ArrayList<String>();
						for (Player p : Game.getInstance().getPlayers()) {
							names.add(p.getName());
						}
						StatisticsManager.getInstance().initialize(Game.getInstance().getGameTurn(), names);
						
						// Display tiles in map screen
						msp.displayTiles(map);
						
						// Register tiles with listeners
						msp.setTileButtonListener(map);
						
						// Shows the first player status on the right player panel
						msp.updatePlayerInfo(Game.getInstance().getCurrentPlayer());
						
						// Display map screen, game starts!
						MainWindow.getInstance().setPanel(panel);
						MainWindow.getInstance().setPauseItemEnable(true);
						MainWindow.getInstance().setSaveItemEnable(true);
						
						// Timer kicks off
						CustomizedTimer myTimer = CustomizedTimer.getInstance(); 
						myTimer.setMapScreenPresenter(msp);
						myTimer.start();
						msp.startOneSecTimer();
					}
					
					// Else continue configuring
					else
					{
						// Reset elements and increment count
						view.reset();
						configCounter++;
					}
				}	
			}
		});
	}
	
	/**
	 * Retrieve information for view and configure one player according to specifications in the game
	 * 
	 * @param modelGame game instance
	 * @return a new player
	 */
	private Player configurePlayer(Game modelGame) {
		// Get information from view
		String name = view.getPlayerName();
		int race = view.getPlayerRace();
		Color color = view.getPlayerColor();
		
		// Configuration
		int money = 0;
		int food = 0;
		int smithore = 0; 
		int energy = 0;
		
		// Allocate food and energy according to game specification
		if (modelGame.getDifficulty() == Game.DIFFICULTY_BEGINNER) {
			food = 8;
			energy = 4;
		} else if (modelGame.getDifficulty() == Game.DIFFICULTY_STANDARD) {
			food = 4;
			energy = 2;
		} else {
			food = 4;
			energy = 2;
		}
		
		// Race
		if (race == Player.RACE_FLAPPER) {
			money = 1600;
		} else if (race == Player.RACE_HUMAN) {
			money = 600;
		} else {
			money = 1000;
		}
		
		return new Player(name, color, race, money, food, smithore, energy);
	}

}
